﻿// -----------------------------------------------------------------------
// <copyright file="Unit.cs" company="DarkBone">
// DarkBone
// </copyright>
// -----------------------------------------------------------------------

namespace DarkBone.Engine.Collections
{
   using System;

   using DarkBone.Engine.SC2;

   /// <summary>
   /// Contains unit information
   /// </summary>
   public sealed class Unit : IComparable
   {
      /// <summary>
      /// Holds SC2.UnitStruct.Id for comparator
      /// </summary>
      private Memory.UnitStruct unitStruct;

      /// <summary>
      /// Initializes a new instance of the <see cref="Unit"/> class.
      /// </summary>
      /// <param name="unitStruct">
      /// The unit struct.
      /// </param>
      public Unit(Memory.UnitStruct unitStruct)
      {
         this.UnitStruct = unitStruct;
      }

      /// <summary>
      /// Gets or sets ModelName.
      /// </summary>
      public string ModelName { get; set; }

      /// <summary>
      /// Gets or sets UnitStruct.
      /// </summary>
      public Memory.UnitStruct UnitStruct
      {
         get
         {
            return this.unitStruct;
         }

         set
         {
            this.unitStruct = value;
         }
      }

      /// <summary>
      /// Gets or sets UpdateTick.
      /// </summary>
      public int UpdateTick { get; set; }

      /// <summary>
      /// Gets or sets Template.
      /// </summary>
      public UnitTemplate.Template Template { get; set; }

      /// <summary>
      /// Gets or sets the X.
      /// </summary>
      /// <value>
      /// The X coord.
      /// </value>
      public int X { get; set; }

      /// <summary>
      /// Gets or sets the Y.
      /// </summary>
      /// <value>
      /// The Y coord.
      /// </value>
      public int Y { get; set; }

      /// <summary>
      /// Compares this to other object
      /// </summary>
      /// <param name="obj">The obj.</param>
      /// <returns>
      /// Zero if object are same
      /// </returns>
      /// <exception cref="T:System.ArgumentException">
      /// <paramref name="obj"/> is not the same type as this instance. </exception>
      public int CompareTo(object obj)
      {
         if (obj is Unit)
         {
            return this.unitStruct.Id.Equals(((Unit)obj).unitStruct.Id) ? 0 : -1;   
         }

         return -1;
      }

      /// <summary>
      /// Overrides Equals
      /// </summary>
      /// <param name="obj">
      /// The obj.
      /// </param>
      /// <returns>
      /// True if object are same
      /// </returns>
      public override bool Equals(object obj)
      {
         return this.CompareTo(obj) == 0;
      }

      /// <summary>
      /// Checks if object is equal
      /// </summary>
      /// <param name="other">
      /// The other.
      /// </param>
      /// <returns>
      /// True if object are equal
      /// </returns>
      public bool Equals(Unit other)
      {
         if (ReferenceEquals(null, other))
         {
            return false;
         }

         return ReferenceEquals(this, other) || other.unitStruct.Equals(this.unitStruct);
      }

      /// <summary>
      /// Gets hashcode of unitStruct.Id
      /// </summary>
      /// <returns>
      /// Hash code
      /// </returns>
      public override int GetHashCode()
      {
         return this.unitStruct.Id.GetHashCode();
      }
   }
}
